from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import datetime
import wmi
import tkinter as tk
from tkinter import simpledialog
from tkinter import scrolledtext

# 加密密钥，长度必须为16、24或32字节，分别对应 AES-128、AES-192和AES-256
encryption_key = b'Hex_Carl_2019_AES_251oslewjs'[:16]  # 确保密钥长度为16字节


def get_local_mac_address():
    try:
        c = wmi.WMI()
        for os in c.Win32_OperatingSystem():
            device_id = os.SerialNumber.strip()
            return device_id
    except Exception as e:
        print(f"Error retrieving device ID: {e}")
        return None


def decrypt_and_validate_license_code(license_code):
    try:
        iv = base64.b64decode(license_code[:24])  # 从授权码中提取IV
        ct = base64.b64decode(license_code[24:])  # 从授权码中提取加密后的信息

        # 使用AES算法进行解密
        cipher = AES.new(encryption_key, AES.MODE_CBC, iv)
        pt = unpad(cipher.decrypt(ct), AES.block_size).decode('utf-8')

        # 解析授权信息
        parts = pt.split('_')
        if len(parts) != 3:
            return False, "解析授权信息时出错"

        mac_address, start_date_str, validity_days_str = parts

        # 验证MAC地址和授权时间
        local_mac_address = get_local_mac_address()
        if mac_address != local_mac_address:
            return False, "MAC地址不匹配"

        start_date = datetime.datetime.strptime(start_date_str, "%Y-%m-%d").date()
        expiration_date = start_date + datetime.timedelta(days=int(validity_days_str))
        today = datetime.date.today()
        if today < start_date or today > expiration_date:
            return False, "授权码已过期"

        return True, "授权验证通过"

    except Exception as e:
        print(f"Error decrypting and validating license code: {e}")
        return False, "验证过程中出现错误"


# 从 myCryption.py 整合的 validate_license_code 函数

def validate_license_code(license_code):
    """
    验证授权码的有效性
    """
    mac_address = get_local_mac_address()
    if not mac_address:
        print("无法获取本地MAC地址")
        return False

    valid, message = decrypt_and_validate_license_code(license_code)
    if valid:
        print("授权验证通过，可以使用软件。")
        return True
    else:
        print(f"授权验证失败：{message}")
        return False


def encrypt_license_info(mac_address, start_date, validity_days):
    try:
        # 构建授权信息
        license_info = f"{mac_address}_{start_date}_{validity_days}"
        # 使用AES算法进行加密
        cipher = AES.new(encryption_key, AES.MODE_CBC)
        ct_bytes = cipher.encrypt(pad(license_info.encode(), AES.block_size))
        iv = base64.b64encode(cipher.iv).decode('utf-8')
        ct = base64.b64encode(ct_bytes).decode('utf-8')
        return iv + ct
    except Exception as e:
        print(f"Error encrypting license info: {e}")
        return None


# 从 myCryption.py 和 creat_license.py 整合的功能

def auto_user_license():
    """
    自动生成用户授权码
    """
    mac_address = get_local_mac_address()
    license_date = "2025-01-01"
    duration = 180
    return encrypt_license_info(mac_address, license_date, duration)

# 从 creat_license.py 整合的功能

def get_user_input():
    """
    获取用户输入的 MAC 地址、授权日期和授权可使用时间
    """
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    mac_address = simpledialog.askstring("MAC Address", "请输入MAC地址:")

    if mac_address:
        license_date = simpledialog.askstring("License Date", "请输入授权日期 (格式: YYYY-MM-DD):")

        try:
            duration = int(simpledialog.askstring("License Duration", "请输入授权可使用时间 (天数):"))
        except ValueError:
            duration = 10  # 默认值

        return mac_address, license_date, duration
    else:
        return None, None, None

# 从 creat_license.py 整合的功能

def show_license_code(license_code):
    """
    显示生成的授权码
    """
    root = tk.Tk()
    root.title("License Code")

    text_widget = scrolledtext.ScrolledText(root, width=40, height=10, wrap=tk.WORD)
    text_widget.pack(fill=tk.BOTH, expand=True)

    text_widget.insert(tk.END, f"License Code:\n{license_code}")

    text_widget.configure(state='normal')
    text_widget.focus_set()

    ok_button = tk.Button(root, text="OK", command=root.destroy, padx=10, pady=5)
    ok_button.pack(pady=5)

    root.mainloop()